package com.topscomm.tap.common;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.topscomm.basic.IBasicService;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboApprovalFlowEntity;
import com.topscomm.cbo.pojo.CboDeptEntity;
import com.topscomm.cbo.pojo.CboItemsEntity;
import com.topscomm.cbo.pojo.CboRoleEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboDeptService;
import com.topscomm.cbo.service.ICboRoleService;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;

@Component(value = "flowDatacodeCache")
@Scope(value = "prototype")
public class FlowDatacodeCache extends DatacodeCache {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * @description:根据用户编码获取适应流程
     * @param itemCode
     * @param userCode
     * @param order
     * @return
     * @author: zhanglongfei
     * @date: 2020年4月14日下午5:14:10
     * @modify:
     */
    public List<Map<String, Object>> getApprovalFlowListMap(String itemCode, String userCode, String order) {
        ICboDeptService deptService = (ICboDeptService) SpringUtil.getBean("cboDeptService");
        ICboUserService userService = (ICboUserService) SpringUtil.getBean("cboUserService");
        ICboRoleService roleService = (ICboRoleService) SpringUtil.getBean("cboRoleService");
        CboUserEntity userEntity = userService.queryObjectByWhere("code = '" + userCode + "'");
        CboDeptEntity deptEntity = deptService.queryById(String.valueOf(userEntity.getDeptid()));
        List<CboRoleEntity> roleList = roleService.queryRolesByUserId(userEntity.getId());
        return getApprovalFlowListMap(itemCode, deptEntity.getCode(), userCode, roleList, order, false);
    }

    /**
     * @description:根据SessionUserBean获取适应流程
     * @param itemCode
     * @param userBean
     * @param order
     * @return
     * @author: zhanglongfei
     * @date: 2020年4月14日下午5:42:02
     * @modify:
     */
    public List<Map<String, Object>> getApprovalFlowListMap(String itemCode, SessionUserBean userBean, String order) {
        ICboRoleService roleService = (ICboRoleService) SpringUtil.getBean("cboRoleService");
        List<CboRoleEntity> roleList = roleService.queryRolesByUserId(userBean.getUser().getId());
        return getApprovalFlowListMap(itemCode, userBean.getDept().getCode(), userBean.getUser().getCode(), roleList,
                order, false);
    }

    /**
     * @author zhanglongfei
     * @date 2019年6月5日
     * @description 通过代码编号、userBean、Order条件来获取代码明细集合，主要用于流程适应
     * @param itemCode
     * @param userBean
     * @param order
     * @return
     */
    public List<Map<String, Object>> getApprovalFlowListMap(String itemCode, String deptCode, String userCode,
                                                            List<CboRoleEntity> roles, String order) {
        return getApprovalFlowListMap(itemCode, deptCode, userCode, roles, order, false);
    }

    /**
     * @author zhanglongfei
     * @date 2019年6月6日
     * @description 通过代码编号、userBean、Order条件来获取代码明细集合，主要用于流程适应，返回单条信息
     * @param itemCode
     * @param userBean
     * @param order
     * @return
     */
    public List<Map<String, Object>> getSingleApprovalFlowMap(String itemCode, String deptCode, String userCode,
                                                              List<CboRoleEntity> roles, String order) {
        return getApprovalFlowListMap(itemCode, deptCode, userCode, roles, order, true);
    }

    /**
     * @author zhanglongfei
     * @date 2019年6月5日
     * @description 通过代码编号、userBean、Order条件来获取代码明细集合，主要用于流程适应
     * @param itemCode
     * @param deptCode
     * @param userCode
     * @param roles
     * @param order
     * @param returnOne
     *            返回单条信息
     * @return
     */
    private List<Map<String, Object>> getApprovalFlowListMap(String itemCode, String deptCode, String userCode,
                                                             List<CboRoleEntity> roles, String order, boolean returnOne) {
        // 查询item对象
        // 查询item对象
        CboItemsEntity item = this.getItemEntity(itemCode);
        if (item == null) {
            return new ArrayList<Map<String, Object>>();
        }
        // 如果不是审批流程
        if (!item.getTargettable().equals(CboApprovalFlowEntity.tableName)) {
            return new ArrayList<Map<String, Object>>();
        }
        // 获取service对象
        IBasicService<?, ?> service = this.getServiceInstance(item);
        // 查询item明细
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendLineSingle(" enabled=1 ");
        if (!StringUtil.isEmpty(item.getTargetcondition())) {
            sql.appendSingle(" and {0} ", item.getTargetcondition());
        }
        String allEmptyWhere = SQLAdapter.isNull("deptcodes", "' '") + " = ' ' and "
                + SQLAdapter.isNull("usercodes", "' '") + " = ' ' and " + SQLAdapter.isNull("roleids", "' '")
                + " = ' '";
        String deptWhere = "1!=1 or ", userWhere = "", roleWhere = "1!=1 or ";
        // 部门配置
        if (deptCode.indexOf("_") < 0)// 不是分公司
        {
            for (int i = 2; i <= deptCode.length(); i = i + 2) {
                deptWhere += SQLAdapter.concat(new String[] { "';'", "deptcodes", "';'" }) + " like '%;"
                        + deptCode.substring(0, i) + ";%' or ";
            }
            if (deptWhere.endsWith("or "))
                deptWhere = deptWhere.substring(0, deptWhere.length() - 3);
        } else if (deptCode.indexOf("_") >= 0) {// 是分公司
            int start_num = deptCode.indexOf("_") + 3;
            for (int i = start_num; i <= deptCode.length(); i = i + 2) {
                deptWhere += SQLAdapter.concat(new String[] { "';'", "REPLACE(deptcodes,'_','')", "';'" }) + " like '%;"
                        + deptCode.substring(0, i).replace("_", "") + ";%' or ";
            }
        }
        if (deptWhere.endsWith("or "))
            deptWhere = deptWhere.substring(0, deptWhere.length() - 3);
        // 人员配置
        userWhere = SQLAdapter.concat(new String[] { "';'", "usercodes", "';'" }) + " like '%;" + userCode + ";%'";
        // 角色配置
        if (roles != null && roles.size() > 0) {
            for (CboRoleEntity roleEntity : roles) {
                roleWhere += SQLAdapter.concat(new String[] { "';'", "roleids", "';'" }) + " like '%;"
                        + roleEntity.getId() + ";%' or ";
            }
        }
        if (roleWhere.endsWith("or "))
            roleWhere = roleWhere.substring(0, roleWhere.length() - 3);
        // 采用如下方式加载：
        // 1、若适应部门、角色、人员都没有选择，则适应所有人
        // 2、若选择了部门、角色、人员其中一项，那么任意一个满足即可
        sql.appendSingle(" and ( ({0}) or ({1}) or ({2}) or ({3}) )", allEmptyWhere, deptWhere, userWhere, roleWhere);
        // 排序，若包含用户，则优先级最高，第二优先级为角色，第三优先级为部门
        if (returnOne) {
            sql.appendSingle(
                    " order by ( (case when ({0}) then 100 else 0 end)+(case when ({1}) then 10 else 0 end)+(case when ({2}) then 1 else 0 end) ) desc{3}",
                    userWhere, roleWhere, deptWhere, (StringUtil.isEmpty(order) ? "" : ("," + order)));
        } else if (!StringUtil.isEmpty(order)) {
            sql.appendSingle(" order by {0} ", order);
        }
        List<String> filedList = new ArrayList<String>();
        filedList.add(item.getIdcol() + " as id");
        filedList.add(item.getCodecol() + " as code");
        filedList.add(item.getNamecol() + " as name");
        filedList.add("extendfield1" + " as nodeptcode");
        List<Map<String, Object>> mapList = service.queryMapFieldsByWhere(sql.toString(), filedList);
        removeExcludeFlowByDeptCode(mapList, deptCode);
        if (returnOne) {
            if (mapList.size() > 1) {
                mapList.subList(1, mapList.size()).clear();
            } else if (mapList.size() == 0) {
                mapList = queryEmptyFlow(filedList);
            }
        }
        return mapList;
    }

    /**
     * @author zhanglongfei
     * @date 2019年6月6日
     * @description 根据部门排除多余的流程
     * @param mapList
     * @param deptCode
     */
    private void removeExcludeFlowByDeptCode(List<Map<String, Object>> mapList, String deptCode) {
        String nodeptcode;
        boolean delFlag = false;
        int start_num = 0;
        for (int num = mapList.size() - 1; num >= 0; num--) {
            delFlag = false;
            nodeptcode = "," + ConvertUtil.convertToString(mapList.get(num).get("nodeptcode"));
            if (StringUtil.isEmpty(nodeptcode))
                continue;
            if (deptCode.indexOf("_") < 0)
                start_num = 2;
            else
                start_num = deptCode.indexOf("_") + 3;
            for (int i = start_num; i <= deptCode.length(); i = i + 2) {
                if (nodeptcode.indexOf("," + deptCode.substring(0, i) + ",") >= 0) {
                    delFlag = true;
                    break;
                }
            }
            if (delFlag)
                mapList.remove(num);
        }
    }

    /**
     * 查询空流程
     *
     * @author zhanglongfei
     * @date 2019年6月6日
     * @description TODO
     * @param filedList
     * @return
     */
    private List<Map<String, Object>> queryEmptyFlow(List<String> filedList) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendLineSingle(" enabled=1 and code = 'Empty'");
        return getServiceInstance("cboApprovalFlowService").queryMapFieldsByWhere(sql.toString(), filedList);
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月24日下午6:18:10
     * @description: 创建服务实例
     * @modify:
     */
    private IBasicService<?, ?> getServiceInstance(CboItemsEntity item) {
        String serviceName = item.getTargettable() + "Service";
        serviceName = StringUtil.lowerFirst(serviceName);
        return getServiceInstance(serviceName);
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月24日下午6:18:10
     * @description: 创建服务实例
     * @modify:
     */
    private IBasicService<?, ?> getServiceInstance(String serviceName) {
        IBasicService<?, ?> service = (IBasicService<?, ?>) SpringUtil.getBean(serviceName);
        return service;
    }
}
